home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / lang / sofa.lha / sofa / smalleiffel / lib_se / run_feature_3.e < prev    next >
Text File  |  2000-03-25  |  18KB  |  631 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
  4. --                       http://SmallEiffel.loria.fr
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License
  11. -- for  more  details.  You  should  have  received a copy of the GNU General
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. class RUN_FEATURE_3
  17.  
  18. inherit RUN_FEATURE;
  19.  
  20. creation make
  21.  
  22. feature
  23.  
  24.    base_feature: PROCEDURE;
  25.  
  26.    arguments: FORMAL_ARG_LIST;
  27.  
  28.    require_assertion: RUN_REQUIRE;
  29.  
  30.    local_vars: LOCAL_VAR_LIST;
  31.  
  32.    routine_body: COMPOUND;
  33.  
  34.    rescue_compound: COMPOUND;
  35.  
  36.    ensure_assertion: E_ENSURE;
  37.  
  38.    is_deferred: BOOLEAN is false;
  39.  
  40.    is_static: BOOLEAN is false;
  41.  
  42.    static_value_mem: INTEGER is 0;
  43.  
  44.    can_be_dropped: BOOLEAN is false
  45.  
  46.    is_once_procedure: BOOLEAN is false;
  47.  
  48.    is_once_function: BOOLEAN is false;
  49.  
  50.    result_type: TYPE is
  51.       do
  52.       end;
  53.  
  54.    is_pre_computable: BOOLEAN is
  55.       do
  56.          if arguments = Void then
  57.             if routine_body = Void then
  58.                Result := true;
  59.             else
  60.                if local_vars = Void then
  61.                   Result := routine_body.is_pre_computable;
  62.                end;
  63.             end;
  64.          end;
  65.       end;
  66.  
  67.    afd_check is
  68.       do
  69.          routine_afd_check;
  70.       end;
  71.  
  72.    mapping_c is
  73.       do
  74.          if isa_in_line then
  75.             if cpp.stack_not_full then
  76.                in_line;
  77.             else
  78.                in_line_status := -1;
  79.                small_eiffel.register_for_c_define(Current);
  80.                mapping_c;
  81.             end;
  82.          else
  83.             default_mapping_procedure;
  84.          end;
  85.       end;
  86.  
  87.    c_define is
  88.       do
  89.          if isa_in_line then
  90.             cpp.incr_inlined_procedure_count;
  91.          elseif c_define_done then
  92.          else
  93.             in_line_status := -2;
  94.             if use_current then
  95.                cpp.incr_procedure_count;
  96.             else
  97.                cpp.incr_real_procedure_count;
  98.             end;
  99.             define_prototype;
  100.             c_define_opening;
  101.             if routine_body /= Void then
  102.                routine_body.compile_to_c;
  103.             end;
  104.             c_define_closing;
  105.             cpp.put_string(fz_12);
  106.             c_frame_descriptor;
  107.          end;
  108.       end;
  109.  
  110.    mapping_jvm is
  111.       do
  112.          routine_mapping_jvm;
  113.       end;
  114.  
  115. feature {CALL_PROC_CALL}
  116.  
  117.    collect_c_tmp is
  118.       do
  119.       end;
  120.  
  121. feature {RUN_FEATURE_3}
  122.  
  123.    initialize is
  124.       do
  125.          arguments := base_feature.arguments;
  126.          if arguments /= Void then
  127.             if not arguments.is_runnable(current_type) then
  128.                !!arguments.with(arguments,current_type);
  129.             end;
  130.          end;
  131.          local_vars := base_feature.local_vars;
  132.          if local_vars /= Void then
  133.             local_vars := local_vars.to_runnable(current_type);
  134.          end;
  135.          routine_body := base_feature.routine_body;
  136.          if routine_body /= Void then
  137.             routine_body := routine_body.to_runnable(current_type);
  138.          end;
  139.          if run_control.require_check then
  140.             require_assertion := run_require;
  141.          end;
  142.          if run_control.ensure_check then
  143.             ensure_assertion := run_ensure;
  144.          end;
  145.          rescue_compound := base_feature.rescue_compound;
  146.          if rescue_compound = Void then
  147.             rescue_compound := default_rescue_compound;
  148.          end;
  149.          if rescue_compound /= Void then
  150.             exceptions_handler.set_used;
  151.             rescue_compound := rescue_compound.to_runnable(current_type);
  152.          end;
  153.       end;
  154.  
  155.    in_line_status: INTEGER;
  156.          -- Possible values :
  157.          --  Value 0 means not computed.
  158.          --  Value -1 means not `isa_in_line' and `c_define' not yet done.
  159.          --  Value -2 means not `isa_in_line' and `c_define' already done.
  160.          --  Other possible values are :
  161.  
  162.    C_empty_or_null_body : INTEGER is 1;
  163.    C_do_not_use_current : INTEGER is 2;
  164.    C_attribute_writer   : INTEGER is 3;
  165.    C_direct_call        : INTEGER is 4;
  166.    C_dca                : INTEGER is 5;
  167.    C_one_pc             : INTEGER is 6;
  168.  
  169.    in_line_status_not_computed: BOOLEAN is
  170.       do
  171.          Result := in_line_status = 0;
  172.       end;
  173.  
  174.    c_define_done: BOOLEAN is
  175.       require
  176.          not isa_in_line
  177.       do
  178.          Result := in_line_status = -2;
  179.       end;
  180.  
  181.    isa_in_line: BOOLEAN is
  182.       do
  183.          if run_control.boost then
  184.             if in_line_status_not_computed then
  185.                if rescue_compound /= Void then
  186.                   in_line_status := -1;
  187.                elseif as_copy = name.to_string then
  188.                   in_line_status := -1;
  189.                elseif empty_or_null_body then
  190.                   in_line_status := C_empty_or_null_body;
  191.                elseif do_not_use_current then
  192.                   in_line_status := C_do_not_use_current;
  193.                elseif attribute_writer then
  194.                   in_line_status := C_attribute_writer;
  195.                elseif direct_call then
  196.                   in_line_status := C_direct_call;
  197.                   -- *** SHOULD USE isa_dca_inline TOO ??
  198.                elseif dca then
  199.                   in_line_status := C_dca;
  200.                elseif one_pc then
  201.                   in_line_status := C_one_pc;
  202.                else
  203.                   in_line_status := -1;
  204.                end;
  205.             end;
  206.             Result := in_line_status > 0;
  207.          end;
  208.       end;
  209.  
  210.    in_line is
  211.       require
  212.          isa_in_line;
  213.       local
  214.          flag: BOOLEAN;
  215.          a: ASSIGNMENT;
  216.          e: EXPRESSION;
  217.          pc: PROC_CALL;
  218.          rf: RUN_FEATURE;
  219.          sfn: SIMPLE_FEATURE_NAME;
  220.          rf2: RUN_FEATURE;
  221.       do
  222.          cpp.put_string("/*[IRF3.");
  223.          cpp.put_integer(in_line_status);
  224.          cpp.put_string(name.to_string);
  225.          cpp.put_string(fz_close_c_comment);
  226.          inspect
  227.             in_line_status
  228.          when C_empty_or_null_body then
  229.             if cpp.cannot_drop_all then
  230.                cpp.put_string(fz_14);
  231.             end;
  232.             if need_local_vars then
  233.                cpp.put_character('{');
  234.                c_define_opening;
  235.                c_define_closing;
  236.                cpp.put_character('}');
  237.             end;
  238.          when C_do_not_use_current then
  239.             if cpp.target_cannot_be_dropped then
  240.                cpp.put_string(fz_14);
  241.             end;
  242.             flag := need_local_vars;
  243.             if flag then
  244.                cpp.put_character('{');
  245.                c_define_opening;
  246.             end;
  247.             routine_body.compile_to_c;
  248.             if flag then
  249.                c_define_closing;
  250.                cpp.put_character('}');
  251.             end;
  252.          when C_attribute_writer then
  253.             flag := need_local_vars;
  254.             if flag then
  255.                cpp.put_character('{');
  256.                c_define_opening;
  257.             end;
  258.             a ?= routine_body.first;
  259.             sfn ?= a.left_side;
  260.             cpp.put_string("(((");
  261.             current_type.mapping_cast;
  262.             cpp.put_character('(');
  263.             cpp.put_target_as_target;
  264.             cpp.put_string(")))->_");
  265.             rf2 := sfn.run_feature_2;
  266.             cpp.put_string(rf2.name.to_string);
  267.             cpp.put_string(")=(");
  268.             e := a.right_side;
  269.             if arguments = Void then
  270.                e.compile_to_c;
  271.             else
  272.                cpp.put_arguments;
  273.             end;
  274.             cpp.put_string(");%N");
  275.             if flag then
  276.                c_define_closing;
  277.                cpp.put_character('}');
  278.             end;
  279.          when C_direct_call then
  280.             flag := need_local_vars;
  281.             if flag then
  282.                cpp.put_character('{');
  283.                c_define_opening;
  284.             end;
  285.             pc ?= routine_body.first;
  286.             rf := pc.run_feature;
  287.             cpp.push_same_target(rf,pc.arguments);
  288.             rf.mapping_c;
  289.             cpp.pop;
  290.             if flag then
  291.                c_define_closing;
  292.                cpp.put_character('}');
  293.             end;
  294.          when C_dca then
  295.             pc ?= routine_body.first;
  296.             pc.finalize;
  297.             cpp.push_inline_dca(Current,pc);
  298.             pc.run_feature.mapping_c;
  299.             cpp.pop;
  300.          when C_one_pc then
  301.             if not use_current then
  302.                if cpp.target_cannot_be_dropped then
  303.                   cpp.put_string(fz_14);
  304.                end;
  305.             end;
  306.             cpp.put_character('{');
  307.             if use_current then
  308.                tmp_string.clear;
  309.                current_type.c_type_for_target_in(tmp_string);
  310.                tmp_string.extend(' ');
  311.                cpp.put_string(tmp_string);
  312.                cpp.inline_level_incr;
  313.                cpp.print_current;
  314.                cpp.inline_level_decr;
  315.                cpp.put_character('=');
  316.                cpp.put_target_as_target;
  317.                cpp.put_string(fz_00);
  318.             end;
  319.             if arguments /= Void then
  320.                arguments.inline_one_pc;
  321.             end;
  322.             if need_local_vars then
  323.                local_vars.inline_one_pc;
  324.                cpp.inline_level_incr;
  325.                local_vars.initialize_expanded;
  326.                cpp.inline_level_decr;
  327.             end;
  328.             cpp.push_inline_one_pc;
  329.             cpp.inline_level_incr;
  330.             routine_body.compile_to_c;
  331.             cpp.inline_level_decr;
  332.             cpp.pop;
  333.             cpp.put_character('}');
  334.          end;
  335.          cpp.put_string("/*]*/%N");
  336.       end;
  337.  
  338.    compute_use_current is
  339.       local
  340.          ct: like current_type;
  341.       do
  342.          ct := current_type;
  343.          if ct.is_reference then
  344.             if run_control.no_check then
  345.                use_current_state := ucs_true;
  346.             else
  347.                std_compute_use_current;
  348.             end;
  349.          else
  350.             std_compute_use_current;
  351.          end;
  352.       end;
  353.  
  354.    empty_or_null_body: BOOLEAN is
  355.          -- The body is empty or has only unreacheable code.
  356.       local
  357.          rb: COMPOUND;
  358.       do
  359.          rb := routine_body;
  360.          Result := (rb = Void or else rb.empty_or_null_body);
  361.       end;
  362.  
  363.    do_not_use_current: BOOLEAN is
  364.       do
  365.          if not routine_body.use_current then
  366.             Result := arguments = Void;
  367.          end;
  368.       end;
  369.  
  370.    attribute_writer: BOOLEAN is
  371.          -- True when body as only one instruction is of
  372.          -- the form :
  373.          --            feature_name := <expression>;
  374.          -- And when <expression> is an argument or a statically
  375.          -- computable value.
  376.       local
  377.          rb: like routine_body;
  378.          a: ASSIGNMENT;
  379.          args: like arguments;
  380.          an2: ARGUMENT_NAME2;
  381.          sfn: SIMPLE_FEATURE_NAME;
  382.       do
  383.          rb := routine_body;
  384.          args := arguments;
  385.          if rb /= Void and then rb.count = 1 then
  386.             a ?= rb.first;
  387.             if a /= Void then
  388.                sfn ?= a.left_side;
  389.                if sfn /= Void then
  390.                   if args = Void then
  391.                      Result := not a.right_side.use_current;
  392.                   elseif args.count = 1 then
  393.                      an2 ?= a.right_side;
  394.                      Result := an2 /= Void;
  395.                   end;
  396.                end;
  397.             end;
  398.          end;
  399.       end;
  400.  
  401.    direct_call: BOOLEAN is
  402.          -- True when the procedure has no arguments, no locals,
  403.          -- and when the body has only one instruction of the
  404.          -- form : foo(<args>);
  405.          -- Where <args> can be an empty list or a statically
  406.          -- computable one and where `foo' is a RUN_FEATURE_3.
  407.       local
  408.          rb: like routine_body;
  409.          pc: PROC_CALL;
  410.          args: EFFECTIVE_ARG_LIST;
  411.          rf3: RUN_FEATURE_3;
  412.       do
  413.          rb := routine_body;
  414.          if rb /= Void and then
  415.             rb.count = 1 and then
  416.             arguments = Void and then
  417.             local_vars = Void
  418.           then
  419.             pc ?= rb.first;
  420.             if pc /= Void then
  421.                if pc.target.is_current then
  422.                   rf3 ?= pc.run_feature;
  423.                   if rf3 /= Void then
  424.                      args := pc.arguments;
  425.                      if args = Void then
  426.                         Result := true;
  427.                      else
  428.                         Result := args.is_static;
  429.                      end;
  430.                   end;
  431.                end;
  432.             end;
  433.          end;
  434.       end;
  435.  
  436.    dca: BOOLEAN is
  437.       local
  438.          pc: PROC_CALL;
  439.          rf: RUN_FEATURE;
  440.          args: EFFECTIVE_ARG_LIST;
  441.       do
  442.          pc := body_one_dpca;
  443.          if pc /= Void and then local_vars = Void then
  444.             rf := pc.run_feature;
  445.             if rf /= Current then
  446.                if rf.current_type.is_user_expanded then
  447.                   -- Not yet inlined :-(
  448.                else
  449.                   args := pc.arguments;
  450.                   if args = Void then
  451.                      Result := arguments = Void;
  452.                   else
  453.                      Result := args.isa_dca_inline(Current,rf);
  454.                   end;
  455.                end;
  456.             end;
  457.          end;
  458.       end;
  459.  
  460.    one_pc: BOOLEAN is
  461.       local
  462.          rb: like routine_body;
  463.          pc: PROC_CALL;
  464.          rf: RUN_FEATURE;
  465.          r: ARRAY[RUN_CLASS];
  466.       do
  467.          rb := routine_body;
  468.          if rb /= Void and then rb.count = 1 then
  469.             pc ?= rb.first;
  470.             if pc /= Void then
  471.                rf := pc.run_feature;
  472.                if rf /= Void and then rf /= Current then
  473.                   r := rf.run_class.running;
  474.                   if r /= Void and then r.count = 1 then
  475.                      Result := true;
  476.                   end;
  477.                end;
  478.             end;
  479.          end;
  480.       end;
  481.  
  482.    body_one_dpca: PROC_CALL is
  483.          -- Gives Void or the only one direct PROC_CALL on
  484.          -- an attribute of Current target.
  485.       local
  486.          rb: like routine_body;
  487.          pc: PROC_CALL;
  488.          c0c: CALL_0_C;
  489.          rf2: RUN_FEATURE_2;
  490.          r: ARRAY[RUN_CLASS];
  491.       do
  492.          if local_vars = Void then
  493.             rb := routine_body;
  494.             if rb /= Void and then rb.count = 1 then
  495.                pc ?= rb.first;
  496.                if pc /= Void then
  497.                   c0c ?= pc.target;
  498.                   if c0c /= Void and then c0c.target.is_current then
  499.                      rf2 ?= c0c.run_feature;
  500.                      if rf2 /= Void then
  501.                         r := rf2.run_class.running;
  502.                         if r /= Void and then r.count = 1 then
  503.                            r := pc.run_feature.run_class.running;
  504.                            if r /= Void and then r.count = 1 then
  505.                               Result := pc;
  506.                            end;
  507.                         end;
  508.                      end;
  509.                   end;
  510.                end;
  511.             end;
  512.          end;
  513.       end;
  514.  
  515.    need_local_vars: BOOLEAN is
  516.       do
  517.          if local_vars /= Void then
  518.             Result := local_vars.produce_c;
  519.          end;
  520.       end;
  521.  
  522.    tmp_string: STRING is
  523.       once
  524.          !!Result.make(32);
  525.       end;
  526.  
  527.    update_tmp_jvm_descriptor is
  528.       do
  529.          routine_update_tmp_jvm_descriptor;
  530.       end;
  531.  
  532. feature {RUN_CLASS}
  533.  
  534.    memory_dispose: like Current is
  535.          -- Squeeze dummy empty `dispose' and set the appropriate
  536.          -- `in_line_status' (no inlining).
  537.       do
  538.          if not is_empty_or_null_body then
  539.             Result := Current;
  540.             in_line_status := -1;
  541.          end;
  542.       end;
  543.  
  544.    jvm_field_or_method is
  545.       do
  546.          jvm.add_method(Current);
  547.       end;
  548.  
  549. feature {JVM}
  550.  
  551.    jvm_define is
  552.       do
  553.          method_info_start;
  554.          jvm_define_opening;
  555.          if routine_body /= Void then
  556.             routine_body.compile_to_jvm;
  557.          end;
  558.          jvm_define_closing;
  559.          code_attribute.opcode_return;
  560.          method_info.finish;
  561.       end;
  562.  
  563. feature {ADDRESS_OF_POOL}
  564.  
  565.    address_of_c_define(caller: ADDRESS_OF) is
  566.       do
  567.          if run_control.boost then
  568.             if isa_in_line then
  569.                address_of_c_define_wrapper(caller);
  570.             elseif use_current then
  571.             else
  572.                address_of_c_define_wrapper(caller);
  573.             end;
  574.          else
  575.             address_of_c_define_wrapper(caller);
  576.          end;
  577.       end;
  578.  
  579. feature {ADDRESS_OF}
  580.  
  581.    address_of_c_mapping is
  582.       do
  583.          if run_control.boost then
  584.             if isa_in_line then
  585.                address_of_c_mapping_wrapper;
  586.             elseif use_current then
  587.                mapping_name;
  588.             else
  589.                address_of_c_mapping_wrapper;
  590.             end;
  591.          else
  592.             address_of_c_mapping_wrapper;
  593.          end;
  594.       end;
  595.  
  596. feature {PROCEDURE}
  597.  
  598.    is_empty_or_null_body: BOOLEAN is
  599.       do
  600.          if isa_in_line then
  601.             Result := in_line_status = C_empty_or_null_body;
  602.          end;
  603.       end;
  604.  
  605.    is_attribute_writer: RUN_FEATURE_2 is
  606.       -- If true, gives the corresponding attribute.
  607.       local
  608.          a: ASSIGNMENT;
  609.          sfn: SIMPLE_FEATURE_NAME;
  610.       do
  611.          if isa_in_line then
  612.             if in_line_status = C_attribute_writer then
  613.                a ?= routine_body.first;
  614.                sfn ?= a.left_side;
  615.                Result := sfn.run_feature_2;
  616.             end;
  617.          end;
  618.       end;
  619.  
  620. feature {NONE}
  621.  
  622.    compute_stupid_switch(r: ARRAY[RUN_CLASS]) is
  623.       do
  624.          std_compute_stupid_switch(r);
  625.       end;
  626.  
  627.    stupid_switch_comment: STRING is "SSPRF3";
  628.  
  629. end -- RUN_FEATURE_3
  630.  
  631.